package com.adk.backend.service.impl;

import com.adk.backend.common.PageResult;
import com.adk.backend.entity.LxBillingDetails;
import com.adk.backend.entity.LxBillingList;
import com.adk.backend.entity.LxOrderList;
import com.adk.backend.mapper.BillingDetailsMapper;
import com.adk.backend.mapper.BillingListMapper;
import com.adk.backend.mapper.OrderListMapper;
import com.adk.backend.service.FinanceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 财务管理服务实现类
 */
@Slf4j
@Service
public class FinanceServiceImpl extends ServiceImpl<BillingListMapper, LxBillingList> implements FinanceService {
    
    @Autowired
    private BillingDetailsMapper billingDetailsMapper;
    
    @Autowired
    private OrderListMapper orderListMapper;
    
    @Override
    public PageResult<Map<String, Object>> getBillList(Map<String, Object> params) {
        Integer pageNum = (Integer) params.getOrDefault("pageNum", 1);
        Integer pageSize = (Integer) params.getOrDefault("pageSize", 20);
        
        Long total = baseMapper.countBillListByCondition(params);
        List<Map<String, Object>> list = baseMapper.selectBillListByCondition(params);
        
        return PageResult.of(total, list, pageNum, pageSize);
    }
    
    @Override
    public LxBillingList getBillByOrderId(Long orderId, Integer shipType) {
        return baseMapper.selectByOrderId(orderId, shipType);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LxBillingList createBill(LxBillingList bill, List<Map<String, Object>> details, Integer userId) {
        // 查询订单信息
        LxOrderList order = orderListMapper.selectById(bill.getOrderId());
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 检查是否已创建账单（与PHP逻辑一致：检查ship_type in (1,2,3,4,7)）
        LxBillingList existing = baseMapper.selectByOrderId(bill.getOrderId(), bill.getShipType());
        if (existing != null) {
            throw new RuntimeException("该订单已创建账单");
        }
        
        int currentTime = (int) (System.currentTimeMillis() / 1000);
        
        // 设置账单信息（与PHP逻辑一致）
        bill.setCustomerId(order.getCustomerId());
        bill.setRecvTime(order.getRecvTime());
        bill.setTotalCtns(order.getTotalCtns());
        bill.setBillDate(new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        bill.setBillDateInt((long) currentTime);
        if (userId != null) {
            bill.setAddUid((long) userId);
        }
        bill.setAddTime(currentTime);
        
        // 计算总金额（与PHP逻辑一致：total_amount = ship_weigth_num * price * exchange_rate）
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (Map<String, Object> detail : details) {
            BigDecimal weight = new BigDecimal(detail.get("shipWeigthNum").toString());
            BigDecimal price = new BigDecimal(detail.get("price").toString());
            BigDecimal rate = new BigDecimal(detail.getOrDefault("exchangeRate", "1").toString());
            totalAmount = totalAmount.add(weight.multiply(price).multiply(rate));
        }
        bill.setTotalAmount(totalAmount);
        
        // 保存账单
        this.save(bill);
        
        // 保存账单明细（与PHP逻辑一致）
        for (Map<String, Object> detail : details) {
            LxBillingDetails billingDetail = new LxBillingDetails();
            billingDetail.setBillId(bill.getId());
            billingDetail.setOrderId(bill.getOrderId());
            billingDetail.setFeeType((Integer) detail.get("feeType"));
            billingDetail.setShipWeigthNum(new BigDecimal(detail.get("shipWeigthNum").toString()));
            billingDetail.setPrice(new BigDecimal(detail.get("price").toString()));
            billingDetail.setCurrencyId((Integer) detail.get("currencyId"));
            billingDetail.setUnitId((Integer) detail.get("unitId"));
            billingDetail.setShipType(bill.getShipType());
            if (detail.containsKey("exchangeRateSar")) {
                billingDetail.setExchangeRateSar(new BigDecimal(detail.get("exchangeRateSar").toString()));
            }
            if (detail.containsKey("exchangeRateUsd")) {
                billingDetail.setExchangeRateUsd(new BigDecimal(detail.get("exchangeRateUsd").toString()));
            }
            billingDetailsMapper.insert(billingDetail);
        }
        
        // 更新订单状态（与PHP逻辑一致：update order_list set is_bill=1, bill_id=$billing_id）
        order.setIsBill(1);
        order.setBillId(bill.getId());
        orderListMapper.updateById(order);
        
        return bill;
    }
    
    @Override
    public boolean updateBill(LxBillingList bill, Integer userId) {
        int currentTime = (int) (System.currentTimeMillis() / 1000);
        bill.setUpdateTime(currentTime);
        if (userId != null) {
            bill.setUpdateUid(userId);
        }
        return this.updateById(bill);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePayStatus(Long billId, Integer paid, BigDecimal paidAmount, Integer userId) {
        LxBillingList bill = this.getById(billId);
        if (bill == null) {
            return false;
        }
        
        // 如果已收款，需要授权码验证（与PHP逻辑一致）
        // TODO: 实现授权码验证逻辑
        // if (bill.getPaid() != null && bill.getPaid() == 1 && paid != 1) {
        //     if (authCode == null || authCode < 1) {
        //         throw new RuntimeException("修改已收款账号需要授权码");
        //     }
        //     // 验证授权码
        //     if (!checkAuthCode(authCode, 1)) {
        //         throw new RuntimeException("授权码无效");
        //     }
        // }
        
        int currentTime = (int) (System.currentTimeMillis() / 1000);
        bill.setPaid(paid);
        bill.setPaidAmount(paidAmount);
        if (paid == 1) {
            bill.setPaidTime(currentTime);
        }
        if (userId != null) {
            bill.setUpdateUid(userId);
        }
        bill.setUpdateTime(currentTime);
        
        return this.updateById(bill);
    }
    
    @Override
    public List<Map<String, Object>> getBillDetails(Long billId) {
        List<LxBillingDetails> details = billingDetailsMapper.selectByBillId(billId);
        List<Map<String, Object>> result = new java.util.ArrayList<>();
        
        for (LxBillingDetails detail : details) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", detail.getId());
            map.put("feeType", detail.getFeeType());
            map.put("shipWeigthNum", detail.getShipWeigthNum());
            map.put("price", detail.getPrice());
            map.put("currencyId", detail.getCurrencyId());
            map.put("unitId", detail.getUnitId());
            result.add(map);
        }
        
        return result;
    }
}

